package org.jsola.hr.provider.impl;

import org.jsola.approval.common.FlowFormCommon;
import org.jsola.approval.constant.ApproType;
import org.jsola.approval.constant.RevokeType;
import org.jsola.approval.constant.UplicateRemovalType;
import org.jsola.approval.dto.ApproFlowAddDTO;
import org.jsola.approval.dto.ApproFlowFormDTO;
import org.jsola.approval.dto.ApproFlowGroupAddDTO;
import org.jsola.approval.dto.ApproFlowSettingDTO;
import org.jsola.approval.service.IApproFlowFormService;
import org.jsola.approval.service.IApproFlowGroupService;
import org.jsola.approval.service.IApproFlowService;
import org.jsola.approval.service.IApproFlowSettingService;
import org.jsola.approval.vo.ApproFlowGroupVO;
import org.jsola.approval.vo.ApproFlowVO;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.provider.IApproInitializerProviderService;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 创建公司初始化的审批
 *
 * @author zxy
 */
@Service("hrApproInitializerProviderServiceImpl")
public class ApproInitializerProviderServiceImpl implements IApproInitializerProviderService {

    @Autowired
    private IApproFlowGroupService flowGroupService;

    @Autowired
    private IApproFlowService flowService;

    @Autowired
    private IApproFlowFormService flowFormService;

    @Autowired
    private IApproFlowSettingService flowSettingService;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void initApproval(String companyId, TokenUser tokenUser) {
        // 假勤管理
        initGruopAttendance(companyId, tokenUser);
        // 人事管理
        initGruopPersonnel(companyId, tokenUser);
        // 财务管理
        initGruopFinance(companyId, tokenUser);
        // 行政管理
        initGruopAdministration(companyId, tokenUser);

        // 将公司下所有审批类型停用
        flowService.leaveAllFlowCompany(companyId, tokenUser);
    }

    /**
     * 审批分类-假勤管理
     *
     * @param tokenUser 当前用户
     */
    private void initGruopAttendance(String companyId, TokenUser tokenUser) {
        // 增加审批分类
        ApproFlowGroupAddDTO flowGroupAddDTO = new ApproFlowGroupAddDTO();
        flowGroupAddDTO.setGroupName("假勤管理");
        flowGroupAddDTO.setGroupDesc("请假考勤管理");
        flowGroupAddDTO.setCompanyId(companyId);
        flowGroupAddDTO.setModuleType("hr");

        ApproFlowGroupVO flowGroup = flowGroupService.save(flowGroupAddDTO, tokenUser);
        // 增加审批分类下审批类型
        // 类型-补卡
        initTypePatchCard(flowGroup.getId(), tokenUser);
        // 类型-加班
        initTypeOvertime(flowGroup.getId(), tokenUser);
        // 类型-换班
        initTypeShiftDuty(flowGroup.getId(), tokenUser);
        // 类型-请假
        initTypeLeave(flowGroup.getId(), tokenUser);
        // 类型-外出
        initTypeGoOut(flowGroup.getId(), tokenUser);
        // 类型-出差
        initTypeBusinessTravel(flowGroup.getId(), tokenUser);
    }

    /**
     * 审批分类-人事管理
     *
     * @param tokenUser 当前用户
     */
    private void initGruopPersonnel(String companyId, TokenUser tokenUser) {
        // 增加审批分类
        ApproFlowGroupAddDTO flowGroupAddDTO = new ApproFlowGroupAddDTO();
        flowGroupAddDTO.setGroupName("人事管理");
        flowGroupAddDTO.setGroupDesc("人事管理");
        flowGroupAddDTO.setCompanyId(companyId);
        flowGroupAddDTO.setModuleType("hr");

        ApproFlowGroupVO flowGroup = flowGroupService.save(flowGroupAddDTO, tokenUser);
        // 增加审批分类下审批类型
        // 类型-入职审批
        initTypeEntry(flowGroup.getId(), tokenUser);
        // 类型-转正
        initTypeToFormal(flowGroup.getId(), tokenUser);
        // 类型-调岗申请
        initTypePostAdjustment(flowGroup.getId(), tokenUser);
        // 类型-离职申请
        initTypeQuit(flowGroup.getId(), tokenUser);
        // 类型-工作交接
        initTypeJobHandover(flowGroup.getId(), tokenUser);
    }

    /**
     * 审批分类-财务管理
     *
     * @param tokenUser 当前用户
     */
    private void initGruopFinance(String companyId, TokenUser tokenUser) {
        // 增加审批分类
        ApproFlowGroupAddDTO flowGroupAddDTO = new ApproFlowGroupAddDTO();
        flowGroupAddDTO.setGroupName("财务管理");
        flowGroupAddDTO.setGroupDesc("财务管理");
        flowGroupAddDTO.setCompanyId(companyId);
        flowGroupAddDTO.setModuleType("hr");

        ApproFlowGroupVO flowGroup = flowGroupService.save(flowGroupAddDTO, tokenUser);
        // 增加审批分类下审批类型
        // 类型-报销
        initTypeReimbursement(flowGroup.getId(), tokenUser);
        // 类型-付款申请
        initTypePayment(flowGroup.getId(), tokenUser);
    }

    /**
     * 审批分类-财务管理
     *
     * @param tokenUser 当前用户
     */
    private void initGruopAdministration(String companyId, TokenUser tokenUser) {
        // 增加审批分类
        ApproFlowGroupAddDTO flowGroupAddDTO = new ApproFlowGroupAddDTO();
        flowGroupAddDTO.setGroupName("行政管理");
        flowGroupAddDTO.setGroupDesc("行政管理");
        flowGroupAddDTO.setCompanyId(companyId);
        flowGroupAddDTO.setModuleType("hr");

        ApproFlowGroupVO flowGroup = flowGroupService.save(flowGroupAddDTO, tokenUser);
        // 增加审批分类下审批类型
        // 类型-采购
        initTypePurchase(flowGroup.getId(), tokenUser);
        // 类型-物品申领
        initTypeReceive(flowGroup.getId(), tokenUser);
    }

    /**
     * 审批类型-补卡
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypePatchCard(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "补卡申请";
        // 描述
        String typeDesc = "当员工考勤出现缺卡时，可发起补卡审批，审批通过后考勤报表中的缺卡记录改为正常";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/zhuanzheng.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, null, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSavePatchCardFormlist(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }

    /**
     * 审批类型-加班
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypeOvertime(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "加班";
        // 描述
        String typeDesc = "适用于加班申请，精确汇总至考勤报表";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/zhuanzheng.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, null, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSaveOvertimeFormlist(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }

    /**
     * 审批类型-换班
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypeShiftDuty(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "换班";
        // 描述
        String typeDesc = "需要与他人换班，或自己不同日期间换班";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/zhuanzheng.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, null, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSaveShiftDutyFormlist(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }


    /**
     * 审批类型-请假
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypeLeave(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "请假";
        // 描述
        String typeDesc = "适用于请假申请，精确扣减出勤日期，并同步考勤报表";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/qingjia.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();

        // 审批类型,请假
        String type = ApproType.LEAVE.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, type, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSaveLeaveFormlist(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }


    /**
     * 审批类型-外出
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypeGoOut(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "外出";
        // 描述
        String typeDesc = "适用于外出申请，精确汇总至考勤报表";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/ruzhi.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, null, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSaveGoOutFormlist(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }


    /**
     * 审批类型-出差
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypeBusinessTravel(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "出差";
        // 描述
        String typeDesc = "适用于出差申请，精确汇总至考勤报表";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/tiaogang.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, null, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSaveBusinessTravelFormlist(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }


    /**
     * 审批类型-入职审批
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypeEntry(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "入职审批";
        // 描述
        String typeDesc = "候选人入职审批";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/ruzhi.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();
        // 审批类型,入职
        String type = ApproType.ON_JOB.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, type, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSaveEntryFormlist(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }


    /**
     * 审批类型-转正
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypeToFormal(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "转正";
        // 描述
        String typeDesc = "用于试用期内员工的员工转正申请";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/zhuanzheng.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();
        // 审批类型,转正
        String type = ApproType.TURN_STRAIGHT.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, type, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSaveToFormalFormlist(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }


    /**
     * 审批类型-调岗申请
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypePostAdjustment(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "调岗申请";
        // 描述
        String typeDesc = "岗位调整申请";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/tiaogang.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();
        // 审批类型,调岗申请
        String type = ApproType.TRANSFER_DUTY.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, type, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSavePostAdjustmentFormlist(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }


    /**
     * 审批类型-离职申请
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypeQuit(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "离职申请";
        // 描述
        String typeDesc = "员工离职申请";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/lizhi.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();
        // 审批类型,离职申请
        String type = ApproType.LEAVING.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, type, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSaveQuitFormlist(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }


    /**
     * 审批类型-离职申请
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypeJobHandover(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "工作交接";
        // 描述
        String typeDesc = "员工工作交接";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/ruzhi.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, null, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSaveJobHandFormlist(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }


    /**
     * 审批类型-报销申请
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypeReimbursement(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "报销";
        // 描述
        String typeDesc = "适用于公司报销审批";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/baoxiao.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();

        // 审批类型,报销
        String type = ApproType.REIMBURSEMENT.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, type, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSaveReimbursementFormlist(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }


    /**
     * 审批类型-付款申请
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypePayment(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "付款申请";
        // 描述
        String typeDesc = "适用于付款审批";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/baoxiao.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, null, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSavePaymentFormlist(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }


    /**
     * 审批类型-付款申请
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypePurchase(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "采购";
        // 描述
        String typeDesc = "用于企业办公或所需材料的采购申请";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/zhuanzheng.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, null, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSavePurchase(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }


    /**
     * 审批类型-付款申请
     *
     * @param flowGroupId 流程分类id
     * @param tokenUser   当前用户
     */
    private void initTypeReceive(String flowGroupId, TokenUser tokenUser) {
        // 基础信息
        // 审批名称
        String typeName = "物品领用";
        // 描述
        String typeDesc = "适用于物品领用申请";
        // 图标
        String icon = "http://hjrl-public.oss-cn-qingdao.aliyuncs.com/icon/approval/tiaogang.png";
        // 撤回操作类型:0:无审批人操作发起人可以撤回;1:未完全通过时候允许撤回
        int revokeType = RevokeType.NOEND.getValue();

        // 构建并保存基础信息
        ApproFlowVO flowVO = buildAndSaveApproFlow(flowGroupId, null, typeName, typeDesc, icon, revokeType, tokenUser);
        String flowId = flowVO.getId();

        // 表单
        buildAndSaveReceive(flowId, tokenUser);

        // 构建并保存流程和高级设置,都一样的
        buildAndSaveProcessAndSetting(flowId, tokenUser);
    }

    /**
     * 构建并保存流程和高级设置,都一样的
     *
     * @param flowId    流程id
     * @param tokenUser 当前用户
     */
    private void buildAndSaveProcessAndSetting(String flowId, TokenUser tokenUser) {

        // 流程,都固定用开始-审批人(自选)-抄送人(自选)-结束的模式
        buildAndSaveProcesee(flowId, tokenUser);

        // 高级设置
        bulidAndSaveFlowSetting(flowId, tokenUser);
    }

    /**
     * 流程,都固定用开始-审批人(自选)-抄送人(自选)-结束的模式
     *
     * @param flowId    流程id
     * @param tokenUser 当前用户
     */
    private void buildAndSaveProcesee(String flowId, TokenUser tokenUser) {
        String str = "";
        str += "	{";
        str += "		'name': '起始节点',";
        str += "		'nodeType': 'start', ";
        str += "		'childNode': { ";
        str += "			'activateType': '0', ";
        str += "			'name': '审批人',";
        str += "			'nodeType': 'approver',";
        str += "			'noneActionerAction': '1', ";
        str += "			'props': { ";
        str += "						'name': '发起人自选',";
        str += "						'type': 'APPROVER_OPTIONAL'";
        str += "					}, ";
        str += "			'childNode': { ";
        str += "				'userIds': '', ";
        str += "				'isUserChose': 'true', ";
        str += "				'nodeType': 'notifier', ";
        str += "				'roles': '', ";
        str += "				'name': '抄送人',";
        str += "				'supervisor': '' ";
        str += "			}";
        str += "		}";
        str += "	}";
        flowService.publishApproFlowProcess(flowId, str, tokenUser);
    }

    /**
     * 构建流程高级设置实体
     *
     * @param flowId    流程id
     * @param tokenUser 当前用户
     */
    private void bulidAndSaveFlowSetting(String flowId, TokenUser tokenUser) {
        ApproFlowSettingDTO flowSettingDTO = new ApproFlowSettingDTO();
        flowSettingDTO.setFlowId(flowId);
        flowSettingDTO.setUplicateRemoval(UplicateRemovalType.NONE.getValue());
        flowSettingDTO.setTipsRemake("");
        flowSettingDTO.setRemakeRequire(false);
        flowSettingDTO.setRemakeShow(true);
        flowSettingDTO.setRemakeEnableOther(false);
        flowSettingService.publishFlowSetting(flowId, flowSettingDTO, tokenUser);
    }

    /**
     * 构建补卡的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSavePatchCardFormlist(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = new ArrayList<>();

        // 补卡日期
        FlowFormCommon.addDateForm("patchCardTime", "补卡日期", "请选择补卡日期", "YYYY-MM-DD", true, formDtoList, flowId);

        // 补卡理由
        FlowFormCommon.addTextareaForm("patchCardReason", "补卡理由", "请填写补卡理由", true, formDtoList, flowId);

        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }

    /**
     * 构建加班的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSaveOvertimeFormlist(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = new ArrayList<>();
        // 加班人
        FlowFormCommon.addChooseUser("applyUser", "加班人", true, true, formDtoList, flowId);

        // 增加时长模块,包含起始日期/结束日期/时长三部分
        FlowFormCommon.addDurationToForm(flowId, formDtoList);

        // 加班原因
        FlowFormCommon.addTextareaForm("reason", "加班原因", "请填写加班原因", false, formDtoList, flowId);

        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }


    /**
     * 构建换班的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSaveShiftDutyFormlist(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = new ArrayList<>();

        // 申请人
        FlowFormCommon.addChooseUser("applyUser", "申请人", false, true, formDtoList, flowId);

        // 交换人
        FlowFormCommon.addChooseUser("exchangeUser", "交换人", false, true, formDtoList, flowId);

        // 换班日期
        FlowFormCommon.addDateForm("shiftDutyTime", "换班日期", "请选择换班日期", "YYYY-MM-DD", true, formDtoList, flowId);

        // 还班日期
        FlowFormCommon.addDateForm("returnTime", "还班日期", "请选择还班日期", "YYYY-MM-DD", true, formDtoList, flowId);

        // 换班原因
        FlowFormCommon.addTextareaForm("reason", "换班原因", "请填写换班原因", false, formDtoList, flowId);

        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }

    /**
     * 构建请假的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSaveLeaveFormlist(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = FlowFormCommon.getFormListByType(flowId, ApproType.LEAVE.getValue());
        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }

    /**
     * 构建外出的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSaveGoOutFormlist(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = new ArrayList<>();

        // 增加时长模块,包含起始日期/结束日期/时长三部分
        FlowFormCommon.addDurationToForm(flowId, formDtoList);

        // 外出事由
        FlowFormCommon.addTextareaForm("reason", "外出事由", "请填写外出事由", false, formDtoList, flowId);

        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }

    /**
     * 构建出差的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSaveBusinessTravelFormlist(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = new ArrayList<>();

        // 出差事由
        FlowFormCommon.addTextareaForm("reason", "出差事由", "请填写出差事由", true, formDtoList, flowId);

        // 出行方式
        FlowFormCommon.addTripTypeForm("tripType", "出行方式", false, formDtoList, flowId);

        // 出发城市
        FlowFormCommon.addCityForm("fromCity", "出发城市", "请选择出发城市", true, formDtoList, flowId);

        // 出发城市
        FlowFormCommon.addCityForm("toCity", "目的城市", "请选择目的城市", true, formDtoList, flowId);

        // 增加时长模块,包含起始日期/结束日期/时长三部分
        FlowFormCommon.addDurationToForm(flowId, formDtoList);

        // 出差备注
        FlowFormCommon.addTextareaForm("remarks", "出差备注", "请填写出差备注", false, formDtoList, flowId);

        // 同行人
        FlowFormCommon.addChooseUser("companion", "同行人", true, false, formDtoList, flowId);

        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }

    /**
     * 构建入职审批的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSaveEntryFormlist(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = FlowFormCommon.getFormListByType(flowId, ApproType.ON_JOB.getValue());
        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }

    /**
     * 构建转正的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSaveToFormalFormlist(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = FlowFormCommon.getFormListByType(flowId, ApproType.TURN_STRAIGHT.getValue());
        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }

    /**
     * 构建调岗的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSavePostAdjustmentFormlist(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = FlowFormCommon.getFormListByType(flowId, ApproType.TRANSFER_DUTY.getValue());
        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }

    /**
     * 构建离职的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSaveQuitFormlist(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = FlowFormCommon.getFormListByType(flowId, ApproType.LEAVING.getValue());
        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }

    /**
     * 构建工作交接的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSaveJobHandFormlist(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = new ArrayList<>();

        // 申请人
        FlowFormCommon.addChooseUser("applyUser", "申请人", false, true, formDtoList, flowId);

        // 部门
        FlowFormCommon.addChooseDepartment("department", "部门", formDtoList, flowId);

        // 交接人
        FlowFormCommon.addChooseUser("receiveUser", "申请人", true, true, formDtoList, flowId);

        // 最后交接日期
        FlowFormCommon.addDateForm("endTime", "截止日期", "请选择截止日期", "YYYY-MM-DD", false, formDtoList, flowId);

        // 交接事项
        FlowFormCommon.addTextareaForm("matter", "交接事项", "请填写交接事项", true, formDtoList, flowId);

        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }

    /**
     * 构建报销的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSaveReimbursementFormlist(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = FlowFormCommon.getFormListByType(flowId, ApproType.REIMBURSEMENT.getValue());
        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }

    /**
     * 构建付款的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSavePaymentFormlist(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = new ArrayList<>();

        // 付款事由
        FlowFormCommon.addTextareaForm("reason", "付款事由", "请填写付款事由", true, formDtoList, flowId);

        // 申请人
        FlowFormCommon.addChooseUser("applyUser", "申请人", false, true, formDtoList, flowId);

        // 申请人
        FlowFormCommon.addChooseUser("payUser", "支付对象", false, true, formDtoList, flowId);

        // 报销金额
        FlowFormCommon.addNumberForm("money", "报销金额(元)", "请填写报销金额", true, formDtoList, flowId);

        // 支付日期
        FlowFormCommon.addDateForm("payTime", "支付日期", "请选择支付日期", "YYYY-MM-DD", false, formDtoList, flowId);

        // 收款账号
        FlowFormCommon.addInputForm("account", "收款账户", "请填写收款账户", true, formDtoList, flowId);

        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }

    /**
     * 构建采购的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSavePurchase(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = new ArrayList<>();

        // 采购事由
        FlowFormCommon.addTextareaForm("reason", "采购事由", "请填写采购事由", true, formDtoList, flowId);

        // 采购类型
        FlowFormCommon.addPurchaseTypeForm("purchaseType", "采购类型", false, formDtoList, flowId);

        // 支付日期
        FlowFormCommon.addDateForm("time", "期待交付日期", "请选择期待交付日期", "YYYY-MM-DD", false, formDtoList, flowId);

        // 物品名称
        FlowFormCommon.addInputForm("name", "物品名称", "请填写物品名称", true, formDtoList, flowId);

        // 物品规格
        FlowFormCommon.addInputForm("specs", "规格", "请填写物品规格", false, formDtoList, flowId);

        // 数量
        FlowFormCommon.addNumberForm("number", "数量", "请填写物品数量", true, formDtoList, flowId);

        // 单价
        FlowFormCommon.addNumberForm("unitPrice", "单价(元)", "请填写物品单价(元)", true, formDtoList, flowId);

        // 总价
        FlowFormCommon.addNumberForm("totalPrice", "总价(元)", "请填写物品总价(元)", true, formDtoList, flowId);

        // 备注
        FlowFormCommon.addTextareaForm("remarks", "备注", "请填写备注", false, formDtoList, flowId);

        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }


    /**
     * 构建物品申领的表单
     *
     * @param flowId    审批类型id
     * @param tokenUser 当前用户
     */
    private void buildAndSaveReceive(String flowId, TokenUser tokenUser) {
        List<ApproFlowFormDTO> formDtoList = new ArrayList<>();

        // 申请人
        FlowFormCommon.addChooseUser("applyUser", "申请人", false, true, formDtoList, flowId);

        // 物品用途
        FlowFormCommon.addInputForm("purpose", "物品用途", "如:日常办公", false, formDtoList, flowId);

        // 物品名称
        FlowFormCommon.addInputForm("name", "物品名称", "请填写物品名称", true, formDtoList, flowId);

        // 物品数量
        FlowFormCommon.addNumberForm("number", "数量", "请填写物品数量", true, formDtoList, flowId);

        // 领用详情
        FlowFormCommon.addTextareaForm("explain", "领用详情", "请填写领用详情", false, formDtoList, flowId);

        flowFormService.publishFlowForm(flowId, formDtoList, tokenUser);
    }


    /**
     * 构建并保存流程基本信息
     *
     * @param flowGroupId 流程分类id
     * @param type        审批类型
     * @param typeName    流程名称
     * @param typeDesc    流程描述
     * @param icon        图标
     * @param revokeType  撤回操作类型
     * @param tokenUser   当前用户
     * @return 流程基础信息
     */
    private ApproFlowVO buildAndSaveApproFlow(String flowGroupId, String type, String typeName, String typeDesc, String icon, int revokeType, TokenUser tokenUser) {
        ApproFlowAddDTO approFlowAddDTO = new ApproFlowAddDTO();
        approFlowAddDTO.setGroupId(flowGroupId);
        approFlowAddDTO.setType(type);
        approFlowAddDTO.setTypeName(typeName);
        approFlowAddDTO.setTypeDesc(typeDesc);
        approFlowAddDTO.setTypeNameAlias(typeName);
        approFlowAddDTO.setIcon(icon);
        approFlowAddDTO.setRevokeType(revokeType);
        approFlowAddDTO.setModuleType("hr");
        // 保存基础信息
        return flowService.save(approFlowAddDTO, tokenUser);
    }
}
